﻿using System.Linq.Expressions;

namespace ORS.OrderRobot.Domain
{
	/// <summary>
	/// 通用仓储接口
	/// </summary>
	/// <typeparam name="TEntity">实体类型</typeparam>
	/// <typeparam name="TKey">主键类型</typeparam>
	public interface IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>
    {
        /// <summary>
        /// 根据ID获取单个实体
        /// </summary>
        /// <param name="id">实体ID</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更，默认为true</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>实体对象</returns>
        Task<TEntity> GetAsync(TKey id, bool includeDetails = false, bool tracking = true, CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据条件获取单个实体
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更，默认为true</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>实体对象</returns>
        Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, bool tracking = true, CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取实体列表
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更，默认为false</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>实体列表</returns>
        Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate = null, bool includeDetails = false, bool tracking = false, CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取实体列表（支持排序）
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="sortingRequests">排序参数列表</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更，默认为false</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>实体列表</returns>
        Task<List<TEntity>> GetListBySortAsync(
            Expression<Func<TEntity, bool>> predicate = null,
            List<SortingRequest> sortingRequests = null,
            bool includeDetails = false,
            bool tracking = false,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取符合条件的实体数量
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>实体数量</returns>
        Task<long> GetCountAsync(Expression<Func<TEntity, bool>> predicate = null, CancellationToken cancellationToken = default);
        
        /// <summary>
        /// 添加单个实体
        /// </summary>
        /// <param name="entity">要添加的实体</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>添加后的实体</returns>
        Task<TEntity> InsertAsync(TEntity entity, CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量添加实体
        /// </summary>
        /// <param name="entities">要添加的实体集合</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task InsertManyAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
        
        /// <summary>
        /// 更新单个实体
        /// </summary>
        /// <param name="entity">要更新的实体</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新后的实体</returns>
        Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量更新实体
        /// </summary>
        /// <param name="entities">要更新的实体集合</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task UpdateManyAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
        
        /// <summary>
        /// 根据ID删除实体
        /// </summary>
        /// <param name="id">要删除的实体ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task DeleteAsync(TKey id, CancellationToken cancellationToken = default);

        /// <summary>
        /// 删除单个实体
        /// </summary>
        /// <param name="entity">要删除的实体</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);

        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="ids">要删除的实体ID集合</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task DeleteManyAsync(IEnumerable<TKey> ids, CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据条件批量删除实体
        /// </summary>
        /// <param name="predicate">删除条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        Task DeleteManyAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default);
        
        /// <summary>
        /// 检查指定ID的实体是否存在
        /// </summary>
        /// <param name="id">实体ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(TKey id, CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查符合条件的实体是否存在
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="pagedRequest">分页参数</param>
        /// <param name="sortingRequest">排序参数</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页结果</returns>
        Task<PagedResult<TEntity>> GetPagedListAsync(
            Expression<Func<TEntity, bool>> predicate = null,
            PagedRequest pagedRequest = null,
            SortingRequest sortingRequest = null,
            bool includeDetails = false,
            bool tracking = false,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 分页查询（支持多字段排序）
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="pagedRequest">分页参数</param>
        /// <param name="sortingRequests">排序参数列表</param>
        /// <param name="includeDetails">是否包含子实体</param>
        /// <param name="tracking">是否跟踪实体变更</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页结果</returns>
        Task<PagedResult<TEntity>> GetPagedListAsync(
            Expression<Func<TEntity, bool>> predicate = null,
            PagedRequest pagedRequest = null,
            List<SortingRequest> sortingRequests = null,
            bool includeDetails = false,
            bool tracking = false,
            CancellationToken cancellationToken = default);
    }
}

